import type { Ref } from 'vue';

import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';

import type { VbenFormSchema } from '#/adapter/form';
import type { OnActionClickFn } from '#/adapter/vxe-table';
import type { MenuApi } from '#/api/system/menu';

import { useAccess } from '@vben/access';

import { getApiList } from '#/api/system/api';
import { getMenuList } from '#/api/system/menu';
import { handleTree } from '#/utils/tree';

const { hasAccessByCodes } = useAccess();

/** 根据菜单类型过滤菜单数据 */
function filterMenuByType(data: any[], menuType?: string): any[] {
  if (!menuType) {
    return data;
  }

  return data.filter((item) => {
    // 顶级菜单总是包含
    if (item.id === 0) {
      return true;
    }

    switch (menuType) {
      case 'C': {
        // 菜单类型：可以选择顶级菜单和目录
        return item.menuType === 'M';
      }
      case 'F': {
        // 按钮类型：可以选择顶级菜单、目录和菜单
        return ['C', 'M'].includes(item.menuType);
      }
      case 'M': {
        // 目录类型：只能选择顶级菜单
        return false;
      }
      default: {
        return true;
      }
    }
  });
}

/** 菜单类型枚举 */
export const MenuTypeEnum = {
  DIR: 'M', // 目录
  MENU: 'C', // 菜单
  BUTTON: 'F', // 按钮
};

/** 菜单类型选项 */
export const menuTypeOptions = [
  { label: '目录', value: 'M' },
  { label: '菜单', value: 'C' },
  { label: '按钮', value: 'F' },
];

/** 新增/修改的表单 */
export function useFormSchema(expandedKeys?: Ref<number[]>): VbenFormSchema[] {
  return [
    {
      component: 'Input',
      fieldName: 'id',
      dependencies: {
        triggerFields: [''],
        show: () => false,
      },
    },
    {
      fieldName: 'systemId',
      label: '所属系统',
      component: 'Input',
      dependencies: {
        triggerFields: [''],
        show: () => false,
      },
    },
    {
      fieldName: 'menuType',
      label: '菜单类型',
      component: 'RadioGroup',
      componentProps: {
        options: menuTypeOptions,
        buttonStyle: 'solid',
        optionType: 'button',
      },
      rules: 'required',
      defaultValue: 'M',
    },
    {
      fieldName: 'pid',
      label: '上级菜单',
      component: 'ApiTreeSelect',
      help: '指当前菜单停靠的菜单归属',
      componentProps: {
        allowClear: true,
        checkStrictly: true,
        api: async (params: any) => {
          // api函数接收params参数
          const systemId = params?.systemId;
          const menuType = params?.menuType;

          // 如果systemId为空，返回空数组避免无效调用
          if (!systemId) {
            return [
              {
                id: 0,
                title: '顶级菜单',
                disabled: false,
              },
            ];
          }
          const data = await getMenuList(systemId);
          data.unshift({
            id: 0,
            title: '顶级菜单',
            disabled: false,
          } as any);

          // 转换数据，确保 disabled 字段是布尔类型
          const transformedData = data.map((item) => ({
            ...item,
            disabled: Boolean(item.disabled),
          }));

          // 根据菜单类型过滤数据
          const filteredData = filterMenuByType(transformedData, menuType);

          return handleTree(filteredData, 'id', 'pid');
        },
        labelField: 'title',
        valueField: 'id',
        childrenField: 'children',
        placeholder: '请选择上级菜单',
        showSearch: true,
        treeDefaultExpandedKeys: expandedKeys?.value || [0],
        // 设置默认展开的节点，当有选中值时自动展开到该节点
        defaultExpandedKeys: expandedKeys?.value || [0],
        filterTreeNode(input: string, node: any) {
          if (!input || input.length === 0) {
            return true;
          }
          const name: string = node.label ?? '';
          if (!name) return false;
          return name.includes(input);
        },
      },
      dependencies: {
        triggerFields: ['systemId', 'menuType'],
        componentProps: (values) => {
          return {
            params: {
              systemId: values.systemId,
              menuType: values.menuType,
            },
          };
        },
      },
      rules: 'required',
    },
    {
      fieldName: 'title',
      label: '菜单标题',
      component: 'Input',
      componentProps: {
        placeholder: '请输入菜单标题',
      },
      rules: 'required',
      help: '菜单位置显示的说明信息',
    },
    {
      fieldName: 'sort',
      label: '显示顺序',
      component: 'InputNumber',
      componentProps: {
        min: 0,
        controlsPosition: 'right',
        placeholder: '请输入显示顺序',
      },
      rules: 'required',
      defaultValue: 1,
    },
    {
      fieldName: 'icon',
      label: '菜单图标',
      component: 'IconPicker',
      componentProps: {
        placeholder: '请选择菜单图标',
        prefix: 'carbon',
      },
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['C', 'M'].includes(values.menuType);
        },
      },
    },
    {
      fieldName: 'name',
      label: '路由名称',
      component: 'Input',
      componentProps: {
        placeholder: '请输入路由名称',
      },
      rules: 'required',
      help: '需要和页面name保持一致，对应页面即可选择缓存',
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['C', 'M'].includes(values.menuType);
        },
      },
    },
    {
      fieldName: 'component',
      label: '组件路径',
      component: 'Input',
      help: '菜单对应的具体vue页面文件路径views的下级路径/admin/sys-api/index；目录类型：填写BasicLayout',
      componentProps: {
        placeholder: '请输入组件路径',
      },
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['C', 'M'].includes(values.menuType);
        },
      },
      rules: 'required',
    },
    {
      fieldName: 'path',
      label: '路由地址',
      component: 'Input',
      help: '访问此页面自定义的url地址，建议/开头书写，例如 /app-name/menu-name',
      componentProps: {
        placeholder: '请输入路由地址',
      },
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['C', 'M'].includes(values.menuType);
        },
      },
      rules: 'required',
    },

    {
      fieldName: 'permission',
      label: '权限标识',
      component: 'Input',
      componentProps: {
        placeholder: '请输入权限标识',
      },
      help: '前端权限控制按钮是否显示',
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['F'].includes(values.menuType);
        },
      },
    },

    {
      fieldName: 'hideInMenu',
      label: '隐藏菜单',
      component: 'RadioGroup',
      componentProps: {
        options: [
          { label: '否', value: 0 },
          { label: '是', value: 1 },
        ],
        buttonStyle: 'solid',
        optionType: 'button',
      },
      defaultValue: 0,
    },
    {
      fieldName: 'ignoreKeepAlive',
      label: '取消页面缓存',
      component: 'RadioGroup',
      componentProps: {
        options: [
          { label: '否', value: 0 },
          { label: '是', value: 1 },
        ],
        buttonStyle: 'solid',
        optionType: 'button',
      },
      defaultValue: 0,
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return values.menuType === 'C';
        },
      },
    },
    {
      fieldName: 'linkFlag',
      label: '是否外链',
      component: 'RadioGroup',
      componentProps: {
        options: [
          { label: '否', value: 0 },
          { label: '是', value: 1 },
        ],
        buttonStyle: 'solid',
        optionType: 'button',
      },
      defaultValue: 0,
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return values.menuType === 'C';
        },
      },
    },
    {
      fieldName: 'link',
      label: '外链地址',
      component: 'Input',
      componentProps: {
        placeholder: '请输入外链地址',
      },
      dependencies: {
        triggerFields: ['linkFlag', 'menuType'],
        show: (values) => {
          return values.menuType === 'C' && values.linkFlag === 1;
        },
      },
    },
    {
      fieldName: 'disabled',
      label: '禁用',
      component: 'RadioGroup',
      componentProps: {
        options: [
          { label: '否', value: 0 },
          { label: '是', value: 1 },
        ],
        buttonStyle: 'solid',
        optionType: 'button',
      },
      defaultValue: 0,
      dependencies: {
        triggerFields: ['menuType'],
        show: (values) => {
          return ['C', 'M'].includes(values.menuType);
        },
      },
    },
    {
      fieldName: 'apiIds',
      label: '关联API',
      component: 'ApiTransfer',
      help: '选择当前菜单/按钮关联的API接口，用于权限控制',
      componentProps: {
        filterable: true,
        titles: ['可选API', '已选API'],
        buttonTexts: ['取消选择', '选择'],
        api: async (params: any) => {
          const systemId = params?.systemId;

          if (!systemId) {
            return [];
          }

          // 调用获取API列表的接口
          const result = await getApiList({
            pageNum: 1,
            pageSize: 999, // 获取所有API数据
            systemId,
          });

          // 转换数据格式以匹配 ApiTransfer 组件的需求
          const apiList = result.list.map((api) => ({
            key: api.id,
            label: `${api.title} - ${api.path}`,
            disabled: false,
          }));
          return apiList;
        },
      },
      dependencies: {
        triggerFields: ['menuType', 'systemId'],
        show: (values) => {
          // 只在按钮(F)类型时显示
          return ['F'].includes(values.menuType);
        },
        componentProps: (values) => {
          return {
            params: { systemId: values.systemId },
          };
        },
      },
    },
  ];
}

/** 列表的字段 */
export function useGridColumns(
  onActionClick: OnActionClickFn<MenuApi.Menu>,
): VxeTableGridOptions<MenuApi.Menu>['columns'] {
  return [
    {
      field: 'title',
      title: '菜单名称',
      minWidth: 250,
      align: 'left',
      fixed: 'left',
      treeNode: true,
      slots: { default: 'title' },
    },
    {
      field: 'menuType',
      title: '菜单类型',
      minWidth: 100,
      cellRender: {
        name: 'CellTag',
        options: [
          { color: 'success', label: '目录', value: 'M' },
          { color: 'warning', label: '菜单', value: 'C' },
          { color: 'danger', label: '按钮', value: 'F' },
        ],
      },
    },
    {
      field: 'sort',
      title: '显示排序',
      minWidth: 100,
    },
    {
      field: 'permission',
      title: '权限标识',
      minWidth: 200,
    },
    {
      field: 'path',
      title: '路由地址',
      minWidth: 200,
    },
    {
      field: 'component',
      title: '组件地址',
      minWidth: 200,
    },
    {
      field: 'name',
      title: '组件名称',
      minWidth: 200,
    },
    {
      field: 'disabled',
      title: '状态',
      minWidth: 100,
      cellRender: {
        name: 'CellTag',
        options: [
          { color: 'success', label: '正常', value: 0 },
          { color: 'danger', label: '停用', value: 1 },
        ],
      },
    },
    {
      field: 'operation',
      title: '操作',
      minWidth: 200,
      fixed: 'right',
      align: 'center',
      cellRender: {
        attrs: {
          nameField: 'title',
          nameTitle: '菜单',
          onClick: onActionClick,
        },
        name: 'CellOperation',
        options: [
          {
            code: 'append',
            text: '新增下级',
            show: (row: MenuApi.Menu) =>
              row.menuType !== MenuTypeEnum.BUTTON &&
              hasAccessByCodes(['system:system:menu:addChildren']),
          },
          {
            code: 'edit',
            show: hasAccessByCodes(['system:system:menu:update']),
          },
          {
            code: 'delete',
            show: hasAccessByCodes(['system:system:menu:update']),
          },
        ],
      },
    },
  ];
}
